
import java.io.IOException;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.game.GameCanvas;
import javax.microedition.lcdui.game.Sprite;


/**
 *
 * @author tkor
 */
public class Game extends GameCanvas{

    
    public static boolean iscontinue = false;
    public int score = 0;
    public rwBC docTam = new rwBC();
    public String user = "An";
    public playmusic abcplay;
    public playmusic abcieuung ;
    public boolean isSound = true;
    private Ball [][] ArrayOfBall;
    private int last_i=-1;
    private int last_j=-1;
    private int nMine=0;
    private int nMineOut=0;
    private int nMineAround=0;
    private int level;
    private boolean is_up_level= false;
    private boolean use_press;
    private boolean createdMineField;
    private Timer mTimer;
    private Timer raceTimer;
    private TimerTask clock;

  
    private Graphics g;
    private Pointer p;
    private Image bg;
    private Hen hen;
    private GameOver Gameover;
    private Remark doubt;
    private Remark sure;
    private Image startInfo;
  
  
    private Sprite countDown;
    private Sprite ball;
    private Sprite ball_sure;
    private Sprite ball_doubt;

  
    private boolean stopped = true;
  
    private SimpleThread gameLogic;
    private Thread countdownThread;

    private int pauseCounter = 0;
    private String error = "";
    private Font smallFont = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_ITALIC, Font.SIZE_SMALL);
    private Font bigFont = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_ITALIC, Font.SIZE_LARGE);
    public Game() {
        super(false);
        setFullScreenMode(true);
       hen=new Hen();
       Gameover=new GameOver();
        doubt=new Remark(0);
        sure=new Remark(1);
       loadGraphics();
        createBalls();
       
        p=null;
        level=0;
        if(!iscontinue)
            is_up_level=true;
        
    }

    public void showNotify() {

       mTimer = new Timer();
        g = getGraphics();
        if(is_up_level) UpLevel();
        TimerTask ui = new TimerTask() { // phụ trách vẽ

            public void run() {
                render(g);
                flushGraphics();
            }
        };
       
        gameLogic = new SimpleThread(40) { // phụ trách tính toán trong game

            public void execute() {
                if (!stopped) {
                }
            }
        };
        gameLogic.start();
       
        mTimer.schedule(ui, 0, 40);
        countdownThread = new Thread() {
            public void run() {
                try {
                    countDown.setFrame(0);
                    pauseCounter = 1;
                    Thread.sleep(1000);
                    countDown.nextFrame();
                    pauseCounter = 2;
                    Thread.sleep(1000);
                    countDown.nextFrame();
                    pauseCounter = 3;
                    Thread.sleep(1000);
                    countDown.nextFrame();
                    Thread.sleep(700);
                    stopped = false;
                } catch (InterruptedException ie) {
                }
            }
        };
        if(isSound){
            abcplay= new playmusic("999_doa_hong.mid");
            abcieuung = new playmusic("GetCoin.wav");
            abcplay.start();
         //   abcplay.play();
        }
        if(!iscontinue)
            countdownThread.start();
        create_contineu();
        
    }
    public void create_contineu(){
         int t = 0;
           if(iscontinue){
               stopped = false;
               nMineOut = 81;
               docTam.doc();
                for(int i = 0; i < 9; i++)
                    for(int j = 0; j <  9 ; j++){
                     if(docTam.array[t] == 1){
                         ArrayOfBall[i][j].ismine=true;
                         nMineOut --;
                     }
                     else
                         ArrayOfBall[i][j].ismine=false;
                     t++;
                    }
                int t_an = 0;
                for(int i = 0; i < 9; i++)
                    for(int j = 0; j <  9 ; j++){
                     if(docTam.array_an[t_an] == 1){
                         ArrayOfBall[i][j].ishide=true;
                         nMineOut --;
                     }
                     else
                         ArrayOfBall[i][j].ishide=false;
                     t_an++;
                    }
                iscontinue = false;
                CountNoMine();
                repaint();
                createdMineField = true;
           }
    }
     public void cleanTrackResources() {
       
        System.gc();
    }
    public void hideNotify() {

        mTimer.cancel();

        if('A' == 65){
            System.out.print("\n a bang 65");
        }
        
        String min ="0", an = "0";
            docTam.deleteStore();
            docTam.openRecStore();
            for(int i= 0 ; i< 9; i++){
                for(int j =0 ; j<9; j++){
                    try{
                        if(ArrayOfBall[i][j].ismine== true){
                            min = "1";
                        }
                        else{
                             min = "0";
                        }

                        if(ArrayOfBall[i][j].ishide == true){
                            an = "1";
                        }
                        else{
                            an = "0";
                        }
                        docTam.writeRecore(min, an);
                    }catch(Exception ex){}
                }
            }
            try{
            docTam.write_sc(Integer.toString(score)/*, user*/);
            }catch(Exception ex){}
            docTam.closeStore();
        
    }

    private void render(Graphics g) {
         int anchor = g.TOP | g.LEFT;
        g.setColor(0xFFFFFF);
        g.fillRect(0, 0, getWidth(), getHeight());
        g.drawImage(bg, 0, 0, anchor);
       
       for(int i=0;i<9;i++)
            for(int j=0;j<9;j++)
            {
                ArrayOfBall[i][j].render(g);
            }
        if (stopped) {
            g.drawImage(startInfo, 0, 66, anchor);
            countDown.paint(g);
        }

        if(p!=null) p.render(g);
        hen.Render(g);
        sure.Render(g);
        doubt.Render(g);
        Gameover.Render(g);
    }

    protected void pointerPressed(int x, int y) {
        if(stopped) return;
         p=null;
         for(int i=0;i<9;i++)
            for(int j=0;j<9;j++)
            {
                if(i!=last_i||j!=last_j)
                if(ArrayOfBall[i][j].OnSelelected(x, y))
                {
                  if(last_i!=-1) ArrayOfBall[last_i][last_j].istouched=false;
                  last_i=i;
                  last_j=j;
                  if(ArrayOfBall[last_i][last_j].ishide)
                      if(p==null) p = new Pointer(ArrayOfBall[last_i][last_j].getX(), ArrayOfBall[last_i][last_j].getY());
                      else p.reset(ArrayOfBall[last_i][last_j].getX(), ArrayOfBall[last_i][last_j].getY());
                  i=9;
                  break;
                }
            }

             if(last_i==-1) // nếu chưa chọn bất kì quả trứng nào
                {
                    last_i=4;
                    last_j=4;
                }
              if(doubt.OnSelelected(x, y))// danh dau nghi ngo
        {
            if(ArrayOfBall[last_i][last_j].isdoubt) ArrayOfBall[last_i][last_j].isdoubt=false;
            else ArrayOfBall[last_i][last_j].isdoubt=true;
        }
        if(sure.OnSelelected(x, y)) // danh dau chac chan
        {
            if(ArrayOfBall[last_i][last_j].issure) ArrayOfBall[last_i][last_j].issure=false;
            else ArrayOfBall[last_i][last_j].issure=true;
        }

           
    }
    private void OpenQuick()
    {
        if(ArrayOfBall[last_i][last_j].nMineAround==CountNoSure(last_i,last_j))
         {
             int r1=last_i==0?0:-1;
             int c1=last_j==0?0:-1;
             int r2=last_i==8?1:2;
             int c2=last_j==8?1:2;
            for(;r1<r2;r1++)
            for(int j=c1;j<c2;j++)
            {
                openField(last_i+r1,last_j+j,false);
            }
         }
    }
    protected void pointerReleased(int x, int y) {
        if(hen.OnSelelected(x, y))
        {
             if(!createdMineField)
                 {
                     createMineField();
                 }
            if(ArrayOfBall[last_i][last_j].ishide)
            {
                OpenQuick();
            }
            else if (openField(last_i, last_j,false)) {
                score = score + 10;
            }
        }
        else hen.OnReleased();
       
    }

    protected void keyPressed(int keyCode) {
        if(stopped) return;
            if(p==null) // khởi tạo vị trí cho con trỏ
            {
                if(last_i==-1) // nếu chưa chọn bất kì quả trứng nào
                {
                    last_i=4;
                    last_j=4;
                }
                // đã chọn 1 quả trứng
                p = new Pointer(ArrayOfBall[last_i][last_j].getX(), ArrayOfBall[last_i][last_j].getY());
            }
        switch (keyCode) {
            case GameCanvas.KEY_NUM2:{ // di chuyển con trỏ lên
               ArrayOfBall[last_i][last_j].istouched=false; // bỏ chọn quả trứng hiện tại
               last_j--;
               if(last_j<0) 
                   last_j=0;
               else
               {
                   p.Up();
               }
               ArrayOfBall[last_i][last_j].OnSelected();// dc chon 
            }
                break;
            case GameCanvas.KEY_NUM4:{
               ArrayOfBall[last_i][last_j].istouched=false;
               last_i--;
               if(last_i<0) last_i=0;
               else
               {
                   p.Left();
               }
               ArrayOfBall[last_i][last_j].OnSelected();
            }
                break;
            case GameCanvas.KEY_NUM6:{
               ArrayOfBall[last_i][last_j].istouched=false;
               last_i++;
               if(last_i>8) last_i=8;
               else
               {
                   p.Right();
               }
               ArrayOfBall[last_i][last_j].OnSelected();
            }
                break;
             case GameCanvas.KEY_NUM8:{
               ArrayOfBall[last_i][last_j].istouched=false;
               last_j++;
               if(last_j>8) last_j=8;
               else
               {
                   p.Down();
               }
               ArrayOfBall[last_i][last_j].OnSelected();
             }
                break;
             case GameCanvas.KEY_NUM5:{
                 if(isSound)
                    abcieuung.play("GetCoin.wav");
                 if(!createdMineField) 
                 {
                     createMineField();
                 }

             }
                break;
        }

    }

    private void loadGraphics() {
        try {
            ImageLoader loader = ImageLoader.getInstance();
        
            countDown = new Sprite(loader.loadImage("/countdown_240x121.png"), 240, 121);
            countDown.setPosition(0, 100);
            countDown.setFrame(0);
           
            startInfo = loader.loadImage("/press_info.png");
            bg=loader.loadImage("/bg.png");
            hen.loadGraphics(loader.loadImage("/hen.png"));
            Gameover.loadGraphics(loader.loadImage("/hen_over.png"), loader.loadImage("/game_over.png"));
             ball = new Sprite(loader.loadImage("/eggs1.png"), 24, 27);
             ball_sure=new Sprite(loader.loadImage("/eggs_sure.png"), 24, 27);
             ball_doubt=new Sprite(loader.loadImage("/eggs_doubt.png"), 24, 27);
            ball.setFrame(0);
            ball_sure.setFrame(0);
            ball_doubt.setFrame(0);
            doubt.loadGraphics(loader.loadImage("/doubt.png"));
            sure.loadGraphics(loader.loadImage("/sure.png"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    private void UpLevel()
    {
        
        level++;
        switch(level)
        {
            case 1:nMine=10;break;
            case 2:nMine=15;break;
            case 3:nMine=20;break;
            case 4:nMine=30;break;
            case 5:nMine=40;break;
        }
         for(int i=0;i<9;i++)
            for(int j=0;j<9;j++)
            {
                ArrayOfBall[i][j].reset();
            }

        nMineOut=81-nMine;
        createdMineField=false;
        is_up_level=false;
        stopped=true;
       if(level!=1 && !iscontinue) countdownThread.run();
    }
    private void createBalls() {
        
        Ball _ball;
        ArrayOfBall=new Ball[9][9];
        for(int i=0;i<9;i++)
            for(int j=0;j<9;j++)
            {
                _ball=new Ball(24*i+12,58+27*j,ball,ball_sure,ball_doubt);
                ArrayOfBall[i][j]=_ball;
            }
        
    }
    
     private int CountNoMine(int last_i,int last_j){

         int n=0;
        int r1=last_i==0?0:-1;
        int c1=last_j==0?0:-1;
        int r2=last_i==8?1:2;
        int c2=last_j==8?1:2;
        for(;r1<r2;r1++)
            for(int j=c1;j<c2;j++)
            {
                if(ArrayOfBall[last_i+r1][last_j+j].ismine) n++;
            }
        return n;
    }
     private int CountNoSure(int last_i,int last_j)
    {
         int n=0;
         int r1=last_i==0?0:-1;
        int c1=last_j==0?0:-1;
        int r2=last_i==8?1:2;
        int c2=last_j==8?1:2;
        for(;r1<r2;r1++)
            for(int j=c1;j<c2;j++)
            {
                if(ArrayOfBall[last_i+r1][last_j+j].issure) n++;
            }
         return n;
     }
     private void CountNoMine(){
            for(int i = 0; i < 9; i++)
                    for(int j = 0; j <  9 ; j++){
                       nMineAround=CountNoMine(i,j);
                             ArrayOfBall[i][j].nMineAround = nMineAround;// dat so min xung quanh thong qua con so
                             nMineAround=0;
                    }
        
    }
      private boolean isAround(int x,int y)
    {
         int r1=last_i==0?0:-1;
        int c1=last_j==0?0:-1;
        int r2=last_i==8?1:2;
        int c2=last_j==8?1:2;
        for(;r1<r2;r1++)
            for(int j=c1;j<c2;j++)
            {
               if(last_i+r1==x&&last_j+j==y) return true;
            }
        return false;
     }

       private void createMineField(){ /// cho nao co min cho nao ko co min //
           if(!createdMineField){
                        int c,r;
                        Random ran=new Random();
                        while(nMine>0)
                        {
                            c=ran.nextInt(9);
                            r=ran.nextInt(9);
                            if(!ArrayOfBall[c][r].ismine&&last_i!=c&&last_j!=r&&!isAround(c,r)){
                                ArrayOfBall[c][r].ismine=true;
                                nMine--;
                            }
               }
           }
        createdMineField=true;
    }
      private void GameOver()
    {
        Gameover.GameOver();
        for(int i = 0; i < 9; i++)
                    for(int j = 0; j <  9 ; j++) if(ArrayOfBall[i][j].ismine) ArrayOfBall[i][j].istouched=true;


      }
       private boolean openField(int last_i,int last_j,boolean is_quick_open)
        {
                if(!is_quick_open) if(ArrayOfBall[last_i][last_j].isdoubt||ArrayOfBall[last_i][last_j].issure) return false;
               if(ArrayOfBall[last_i][last_j].ishide) return false;
                if(!ArrayOfBall[last_i][last_j].ismine)
                     {
                        nMineOut--;// so o duoc mo tru xuong
                        if(nMineOut==0)
                        {
                            is_up_level = true;
                            UpLevel();
                            return false;
                        }
                        nMineAround=CountNoMine(last_i,last_j);
                         if(nMineAround==0)// neu ko co minh xung quanh
                         {

                             ArrayOfBall[last_i][last_j].ishide = true;
                             int r1=last_i==0?0:-1;
                             int c1=last_j==0?0:-1;
                              int r2=last_i==8?1:2;
                             int c2=last_j==8?1:2;
                             for(;r1<r2;r1++)
                            for(int j=c1;j<c2;j++)
                            {
                                 openField(last_i+r1,last_j+j,false);
                             }
                             return true;
                         }
                         else
                         {
                             ArrayOfBall[last_i][last_j].setNoMineAround(nMineAround);// dat so min xung quanh thong qua con so
                             nMineAround=0;// tro ve bang 0
                             return true;
                         }
                     }
                else GameOver();
                return false;
        }
     
       protected void keyReleased(int keyCode) {
           if(stopped) return;
        switch (keyCode) {
             case GameCanvas.KEY_NUM5:{
                 if(isSound)
                    abcieuung.close();
                 if(openField(last_i,last_j,false)) score = score + 10;
             }
                break;
            case GameCanvas.KEY_NUM1:{


            if(ArrayOfBall[last_i][last_j].isdoubt) ArrayOfBall[last_i][last_j].isdoubt=false;
            else ArrayOfBall[last_i][last_j].isdoubt=true;
        
            }break;
            case GameCanvas.KEY_NUM3:{


            if(ArrayOfBall[last_i][last_j].issure) ArrayOfBall[last_i][last_j].issure=false;
            else ArrayOfBall[last_i][last_j].issure=true;

            }break;

        }
    }
    public void exit() {
        exit();
    }
    
    
}
